package com.qfedu.knowledge.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.qfedu.knowledge.dao.IQuestionInfoDao;
import com.qfedu.knowledge.dao.IQuestionRecordDao;
import com.qfedu.knowledge.entity.bo.QuestionInfoBO;
import com.qfedu.knowledge.entity.bo.QuestionRecordBO;
import com.qfedu.knowledge.entity.dto.BasePageDTO;
import com.qfedu.knowledge.entity.dto.QueryDTO;
import com.qfedu.knowledge.entity.dto.QuestionInfoDTO;
import com.qfedu.knowledge.entity.enums.ResultEnum;
import com.qfedu.knowledge.entity.vo.PageResult;
import com.qfedu.knowledge.entity.vo.QuestionInfoVO;
import com.qfedu.knowledge.exception.BusinessRuntimeException;
import com.qfedu.knowledge.service.IQuestionInfoService;
import com.qfedu.knowledge.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @ClassName QuestionInfoServiceImpl
 * @Author ykx
 * @Date 2024/1/3 10:19
 * @Version 1.0
 */
@Service
public class QuestionInfoServiceImpl extends ServiceImpl<IQuestionInfoDao, QuestionInfoBO> implements IQuestionInfoService {

    @Autowired
    private IQuestionInfoDao questionInfoDao;

    @Autowired
    private IQuestionRecordDao questionRecordDao;

    @Autowired
    private SecurityUtils securityUtils;

    /**
     * @return List<QuestionInfoVO>
     */
    @Override
    public PageResult<QuestionInfoVO> getQuestionInfoByPage(BasePageDTO basePageDTO, QueryDTO queryDTO) {
        Long userId = securityUtils.getCurrentUser().getId();
        PageHelper.startPage(basePageDTO.getPage(), basePageDTO.getSize());
        return new PageResult<>(new PageInfo<>(questionInfoDao.getQuestionInfoByPage(userId, queryDTO)));
    }

    @Override
    public Boolean addQuestion(QuestionInfoDTO questionInfoDTO) {
        // 校验题目
        checkQuestionInfo(questionInfoDTO);

        QuestionInfoBO questionInfoBO = QuestionInfoBO.BuildQuestion(questionInfoDTO);
        if (StringUtil.isEmpty(questionInfoBO.getAnswer()) && Objects.nonNull(questionInfoDTO.getAnswerOption()))
            setQuestionAnswer(questionInfoBO, questionInfoDTO);

        return save(questionInfoBO);
    }

    @Override
    public QuestionInfoVO getBaseInfoById(Long id) {
        QuestionInfoVO questionInfoVO = questionInfoDao.getBaseInfoById(id);

        if (Objects.isNull(questionInfoVO)) {
            throw new BusinessRuntimeException(ResultEnum.QUESTION_NULL);
        }

        return questionInfoVO;
    }

    @Override
    @Transactional
    public Boolean updQuestionInfo(QuestionInfoDTO questionInfoDTO) {
        QuestionInfoBO questionInfoBO = QuestionInfoBO.BuildQuestion(questionInfoDTO);

        // 插入流程进展记录
        String record = createRecord(questionInfoDTO.getId(), questionInfoDTO);
        QuestionRecordBO recordForUpdInfo = QuestionRecordBO.createRecordForUpdInfo(questionInfoDTO.getId(), record);
        questionRecordDao.insert(recordForUpdInfo);

        return saveOrUpdate(questionInfoBO);
    }

    /**
     * 创建进展记录
     *
     * @param questionId      questionId
     * @param questionInfoDTO 修改后的数据信息
     * @return String
     */
    private String createRecord(Long questionId, QuestionInfoDTO questionInfoDTO) {
        // 流程进展记录结果
        List<String> messageList = new ArrayList<>();

        // 原数据信息
        QuestionInfoBO questionInfoBO = getById(questionId);

        // 选项ABCD，不相同时插入
        if (!Objects.equals(questionInfoBO.getOptionA(), questionInfoDTO.getOptionA())) {
            if (StringUtil.isEmpty(questionInfoBO.getOptionA()) && StringUtil.isNotEmpty(questionInfoDTO.getOptionA())) {
                messageList.add("新增了选项A：" + questionInfoDTO.getOptionA());
            }
            if (StringUtil.isNotEmpty(questionInfoBO.getOptionA()) && StringUtil.isNotEmpty(questionInfoDTO.getOptionA())) {
                messageList.add("选项A由" + questionInfoBO.getOptionA() + "变成" + questionInfoDTO.getOptionA());
            }
            if (StringUtil.isNotEmpty(questionInfoBO.getOptionA()) && StringUtil.isEmpty(questionInfoDTO.getOptionA())) {
                messageList.add("删除了选项A：" + questionInfoBO.getOptionA());
            }
        }

        if (!Objects.equals(questionInfoBO.getOptionB(), questionInfoDTO.getOptionB())) {
            if (StringUtil.isEmpty(questionInfoBO.getOptionB()) && StringUtil.isNotEmpty(questionInfoDTO.getOptionB())) {
                messageList.add("新增了选项B：" + questionInfoDTO.getOptionB());
            }
            if (StringUtil.isNotEmpty(questionInfoBO.getOptionB()) && StringUtil.isNotEmpty(questionInfoDTO.getOptionB())) {
                messageList.add("选项B由" + questionInfoBO.getOptionB() + "变成" + questionInfoDTO.getOptionB());
            }
            if (StringUtil.isNotEmpty(questionInfoBO.getOptionB()) && StringUtil.isEmpty(questionInfoDTO.getOptionB())) {
                messageList.add("删除了选项B：" + questionInfoBO.getOptionB());
            }
        }

        if (!Objects.equals(questionInfoBO.getOptionC(), questionInfoDTO.getOptionC())) {
            if (StringUtil.isEmpty(questionInfoBO.getOptionC()) && StringUtil.isNotEmpty(questionInfoDTO.getOptionC())) {
                messageList.add("新增了选项C：" + questionInfoDTO.getOptionC());
            }
            if (StringUtil.isNotEmpty(questionInfoBO.getOptionC()) && StringUtil.isNotEmpty(questionInfoDTO.getOptionC())) {
                messageList.add("选项C由" + questionInfoBO.getOptionC() + "变成" + questionInfoDTO.getOptionC());
            }
            if (StringUtil.isNotEmpty(questionInfoBO.getOptionC()) && StringUtil.isEmpty(questionInfoDTO.getOptionC())) {
                messageList.add("删除了选项C：" + questionInfoBO.getOptionC());
            }
        }

        if (!Objects.equals(questionInfoBO.getOptionD(), questionInfoDTO.getOptionD())) {
            if (StringUtil.isEmpty(questionInfoBO.getOptionD()) && StringUtil.isNotEmpty(questionInfoDTO.getOptionD())) {
                messageList.add("新增了选项D：" + questionInfoDTO.getOptionD());
            }
            if (StringUtil.isNotEmpty(questionInfoBO.getOptionD()) && StringUtil.isNotEmpty(questionInfoDTO.getOptionD())) {
                messageList.add("选项D由" + questionInfoBO.getOptionD() + "变成" + questionInfoDTO.getOptionD());
            }
            if (StringUtil.isNotEmpty(questionInfoBO.getOptionD()) && StringUtil.isEmpty(questionInfoDTO.getOptionD())) {
                messageList.add("删除了选项D：" + questionInfoBO.getOptionD());
            }
        }

        // 拼接成含序号的字符串
        StringBuilder result = new StringBuilder();
        if (!messageList.isEmpty()) {
            for (int i = 0; i < messageList.size(); i++) {
                result.append(";" + (i + 1) + "." + messageList.get(i));
            }
        }

        return result.toString().substring(1);
    }

    /**
     * 校验题目
     *
     * @param questionInfoDTO questionInfoDTO
     */
    private void checkQuestionInfo(QuestionInfoDTO questionInfoDTO) {
        // 选项为空时，答案不能为空
        if (QuestionInfoDTO.isNonOption(questionInfoDTO)
                && StringUtil.isEmpty(questionInfoDTO.getAnswer())) {
            throw new BusinessRuntimeException(ResultEnum.ANSWER_NULL);
        }

        // 选项不为空时，答案选项不能为空
        if (!QuestionInfoDTO.isNonOption(questionInfoDTO)
                && StringUtil.isEmpty(questionInfoDTO.getAnswerOption())) {
            throw new BusinessRuntimeException(ResultEnum.ANSWER_OPTION_NULL);
        }
    }

    /**
     * 根据选项设置答案
     *
     * @param questionInfoBO  questionInfoBO
     * @param questionInfoDTO questionInfoDTO
     */
    private void setQuestionAnswer(QuestionInfoBO questionInfoBO, QuestionInfoDTO questionInfoDTO) {
        switch (questionInfoDTO.getAnswerOption()) {
            case "A":
                questionInfoBO.setAnswer(questionInfoDTO.getOptionA());
                break;
            case "B":
                questionInfoBO.setAnswer(questionInfoDTO.getOptionB());
                break;
            case "C":
                questionInfoBO.setAnswer(questionInfoDTO.getOptionC());
                break;
            case "D":
                questionInfoBO.setAnswer(questionInfoDTO.getOptionD());
                break;
            default:
                log.error("答案选项错误");
                break;
        }
    }


}
